# coding:utf-8
"""
    pyclamd模块的一个实例,实现集中式病毒扫描.
"""
import time
from threading import Thread

import pyclamd


class Scan(Thread):
    """主要的类"""
    def __init__(self, IP, scan_type, file):
        """构造方法,初始化"""
        Thread.__init__(self)
        self.ip = IP
        self.scan_type = scan_type
        self.file = file
        self.connstr = ""
        self.scanresult = ""

    def run(self):
        """多进程run方法"""
        try:
            cd = pyclamd.ClamdNetworkSocket(self.ip, 3310)  # 创建网络套接字对象
            if cd.ping():  # 探测连通性
                self.connstr = self.ip + " connection [OK]"
                cd.reload()  # 强制重载特征库 更新特征库

                # 通过EICAR()方法生成一个带有病毒特征的文件/tmp/EICAR 测试用
                # void = open('/tmp/EICAR','w').write(cd.EICAR())
                
                if self.scan_type == "contscan_file":  # 选择不同的扫描模式
                    self.scanresult = "{0}\n".format(
                        cd.contscan_file(self.file))
                elif self.scan_type == "multiscan_file":
                    self.scanresult = "{0}\n".format(
                        cd.multiscan_file(self.file))

                elif self.scan_type == "scan_file":
                    self.scanresult = "{0}\n".format(cd.scan_file(self.file))

                time.sleep(1)  # 暂停1秒
            else:
                self.connstr = self.ip + " ping error,exit"
                return

        except Exception as e:
            self.connstr = self.ip + " " + str(e)


def main():
    '''主函数'''
    IPs = ['192.168.1.21', '192.168.1.22']  # 扫描主机列表
    scantype = 'multiscan_file'  # 指定扫描模式,支持multiscan_file contscan_file scan_file
    scanfile = '/data/www'  # 指定扫描路径
    i = 1

    threadnum = 2  # 指定启动的线程数
    scanlist = []  # 存储扫描Scan类型的队列

    for ip in IPs:
        currp = Scan(ip, scantype, scanfile)  # 创建扫描Scan类对象
        scanlist.append(currp)  # 把对象追加到列表

        if i % threadnum == 0 or i == len(IPs):  # 当到达制定的线程数或IP列表数后启动,退出线程
            for task in scanlist:
                task.start()  # 启动线程

            for task in scanlist:
                task.join()  # 等待所有子线程退出,并输出扫描结果
                print(task.connstr)  # 　打印服务器连接信息
                print(task.scanresult)  # 打印扫描结果
            scanlist = []
        i += 1


if __name__ == '__main__':
    main()
